package com.bitdf.txing.chat.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bitdf.txing.chat.constant.Constant;
import com.bitdf.txing.chat.dao.ChatMessageDao;
import com.bitdf.txing.chat.entity.ChatMessageEntity;
import com.bitdf.txing.chat.entity.ReadMessageEntity;
import com.bitdf.txing.chat.service.ReadMessageService;
import com.bitdf.txing.chat.service.RedisService;
import com.bitdf.txing.chat.utils.RedisUtil;
import com.bitdf.txing.common.vo.UserInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Lizhiwei
 * @date 2022/11/26 1:05:23
 * 注释：
 */
@Service
@Slf4j
public class RedisServiceImpl implements RedisService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //    @Autowired
//    private ChatMessageService chatMessageService;
    @Autowired
    private ChatMessageDao chatMessageDao;
    @Autowired
    private ReadMessageService readMessageService;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public boolean saveChatMessageToRedis(ChatMessageEntity messageEntity) {
        boolean b = redisUtil.saveChatMessage(messageEntity, stringRedisTemplate);
        return b;
    }

    @Override
    public List<ChatMessageEntity> getHistoryMessage(String chatKey) {
        List<ChatMessageEntity> list = null;
        List<String> strList = stringRedisTemplate.opsForList().range(chatKey, 0, 15);
        if (strList == null || strList.size() == 0) {

            String[] split = chatKey.split(":");
            String s = split[split.length - 1];
            String[] split1 = s.split("-");
            Long min = Long.parseLong(split1[0]);
            Long max = Long.parseLong(split1[1]);

            list = chatMessageDao.selectList(new QueryWrapper<ChatMessageEntity>().and(query -> {
                        query.eq("from_user_id", min).eq("to_target_id", max).or((query1) -> {
                            query1.eq("from_user_id", max).eq("to_target_id", min);
                        });
                    }).and(query -> {
                        query.eq("type", Constant.SINGLE_SENDING);
                    })
                    .orderByDesc("create_time").last(" limit 0,15"));

            if (list == null || list.size() == 0) {
                return null;
            }
            //存进redis
            Boolean b = RedisUtil.rightPushByList(chatKey, list, stringRedisTemplate);
            return list;
        }
        list = strList.stream().map((item) -> {
            ChatMessageEntity entity = JSON.parseObject(item, ChatMessageEntity.class);
            return entity;
        }).collect(Collectors.toList());
        return list;
    }

    @Override
    public List<ChatMessageEntity> getHistoryMessage(String chatKey, Integer start, Integer count) {
        List<String> range = stringRedisTemplate.opsForList().range(chatKey, start, start + count);
        if (range == null || range.size() == 0) {
            return null;
        }
        List<ChatMessageEntity> collect = range.stream().map((s) -> {
            return JSON.parseObject(s, ChatMessageEntity.class);
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public Map<Long, Date> getFriendsLastReadTime(long l, List<UserInfoVo> friendsList) {
        if(friendsList==null || friendsList.size()==0){
            return null;
        }
        Map<Long, Date> collect = friendsList.stream().collect(Collectors.toMap((item) -> {
            return item.getId();
        }, (item) -> {
            String s = stringRedisTemplate.opsForValue().get(Constant.CHATREADTIME + item.getId() + "-" + l);
            if (s != null && !s.equals("")) {
                Date date = JSON.parseObject(s, Date.class);
                return date;
            } else {
                ReadMessageEntity entity = readMessageService.getOne(new QueryWrapper<ReadMessageEntity>().eq("read_user_id", item.getId())
                        .eq("send_user_id", l));
                if (entity != null) {
                    stringRedisTemplate.opsForValue().set(Constant.CHATREADTIME + item.getId() + "-" + l, JSON.toJSONString(entity.getReadTime()));
                    return entity.getReadTime();
                } else {
                    //返回null会报空值异常
//                    return new Date("1970-01-01 00:00:00");
                    return new Date(1970, 01, 01, 0, 0, 0);
                }
            }
        }));
        return collect;
    }

    /**
     * 获取某用户对在redis中的所有的聊天记录
     * @param chatKey
     * @return
     */
    @Override
    public List<ChatMessageEntity> getRedisAllHistoryMessage(String chatKey) {
        List<ChatMessageEntity> list = null;
        List<String> strList = stringRedisTemplate.opsForList().range(chatKey, 0, -1);
        if (strList != null && strList.size() > 0) {
            list = strList.stream().map((item) -> {
                ChatMessageEntity entity = JSON.parseObject(item, ChatMessageEntity.class);
                return entity;
            }).collect(Collectors.toList());
        }
        return list;
    }

    /**
     * 获取群聊历史信息 前15条
     *
     * @param chatKey
     * @return
     */
    @Override
    public List<ChatMessageEntity> getGroupHistoryMessage(String chatKey) {
        List<ChatMessageEntity> list = null;
        List<String> strList = stringRedisTemplate.opsForList().range(chatKey, 0, 15);
        if (strList == null || strList.size() == 0) {
            // 如果Redis中查不到  就到数据库查 并且存进Redis
            String[] split = chatKey.split(":");
            String s = split[split.length - 1];
            Long groupId = Long.parseLong(s);

            list = chatMessageDao.selectList(new QueryWrapper<ChatMessageEntity>().and(query -> {
                        query.eq("to_target_id", groupId);
                    }).and(query -> {
                        query.eq("type", Constant.GROUP_SENDING);
                    })
                    .orderByDesc("create_time").last(" limit 0,15"));


            if (list != null && list.size() > 0) {
                //存进redis
                Boolean b = RedisUtil.rightPushByList(chatKey, list, stringRedisTemplate);
            }
            return list;
        }
        list = strList.stream().map((item) -> {
            ChatMessageEntity entity = JSON.parseObject(item, ChatMessageEntity.class);
            return entity;
        }).collect(Collectors.toList());
        return list;
    }

    @Override
    public boolean updateReadMessageTime(ReadMessageEntity entity)  {
        String value = JSON.toJSONString(entity.getReadTime());
        try {
            stringRedisTemplate.opsForValue().set(Constant.CHATREADTIME + entity.getReadUserId() + "-" + entity.getSendUserId(), value);
            stringRedisTemplate.expire(Constant.CHATREADTIME + entity.getReadUserId() + "-" + entity.getSendUserId(), Duration.ofHours(2));
            return true;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
